import type { AIMessage, AIProvider, CharacterData } from './types.js';

// 抽象AI提供商基类
export abstract class BaseAIProvider implements AIProvider {
  protected config: {
    apiKey: string;
    baseURL: string;
    model: string;
  };

  constructor(config: { apiKey: string; baseURL: string; model: string }) {
    this.config = config;
  }

  abstract getName(): string;
  abstract callAPI(messages: AIMessage[]): Promise<any>;

  // 检查配置是否有效
  isConfigured(): boolean {
    return !!(this.config.apiKey && this.config.baseURL && this.config.model);
  }

  // 默认的响应清理方法
  cleanResponse(content: string): string {
    // 移除markdown代码块标记
    let cleaned = content.replace(/```json\s*/g, '').replace(/```\s*/g, '');

    // 移除可能的前后空白字符
    cleaned = cleaned.trim();

    // 如果内容以非JSON字符开头，尝试提取JSON部分
    const jsonStart = cleaned.indexOf('{');
    const jsonEnd = cleaned.lastIndexOf('}');

    if (jsonStart !== -1 && jsonEnd !== -1 && jsonEnd > jsonStart) {
      cleaned = cleaned.substring(jsonStart, jsonEnd + 1);
    }

    return cleaned;
  }

  // 默认的角色生成方法
  async generateCharacter(background: string): Promise<CharacterData> {
    const prompt = `基于以下故事背景，生成一个详细的角色人设：

故事背景：
${background}

请生成包含以下要素的角色，直接返回JSON格式，不要包含任何其他文字或markdown标记：

{
  "name": "角色姓名",
  "personality": ["性格特点1", "性格特点2", "性格特点3"],
  "speakingStyle": "说话风格描述",
  "knowledgeBase": "角色的知识领域和专长"
}

要求：
1. 角色姓名要符合背景设定
2. 性格特点要具体且有特色（3-5个）
3. 说话风格要生动有趣
4. 知识领域要与背景相关
5. 只返回JSON，不要任何解释文字或代码块标记`;

    try {
      const response = await this.callAPI([{ role: 'user', content: prompt }]);
      const content = response.choices[0].message.content;
      
      console.log(`[${this.getName()}] AI原始返回内容:`, content);

      // 清理AI返回的内容
      const cleanContent = this.cleanResponse(content);
      console.log(`[${this.getName()}] 清理后的内容:`, cleanContent);

      const characterData = JSON.parse(cleanContent);

      // 验证必要字段
      if (
        !characterData.name ||
        !characterData.personality ||
        !characterData.speakingStyle ||
        !characterData.knowledgeBase
      ) {
        throw new Error('AI返回的角色数据不完整');
      }

      return characterData;
    } catch (error) {
      console.error(`[${this.getName()}] 生成角色失败:`, error);
      if (error instanceof SyntaxError) {
        throw new Error('AI返回的数据格式错误，请重试');
      }
      throw new Error('角色生成失败，请重试');
    }
  }

  // 默认的对话方法
  async chat(messages: AIMessage[]): Promise<string> {
    try {
      const response = await this.callAPI(messages);
      return response.choices[0].message.content;
    } catch (error) {
      console.error(`[${this.getName()}] 对话失败:`, error);
      throw new Error('对话失败，请重试');
    }
  }

  // 生成系统提示词
  protected generateSystemPrompt(character: CharacterData): string {
    return `你是${character.name}，一个虚拟角色。

性格特点：
${character.personality.join('、')}

说话风格：
${character.speakingStyle}

知识领域：
${character.knowledgeBase}

请严格按照以上设定进行角色扮演，保持角色的一致性。用第一人称回应用户，不要透露你是AI助手的身份。回答要生动有趣，符合角色设定。`;
  }
}
